#pragma once

#include <algorithm> // For std::swap (though not strictly needed for std::chrono::time_point)
#include <chrono>
#include <cstdint> // For int64_t
#include <ctime>   // For time_t, tm, gmtime_r (or localtime_s/gmtime_s on Windows)
#include <iomanip> // For std::put_time
#include <sstream> // For std::ostringstream
#include <string>

// Helper for gmtime_r or equivalent thread-safe gmtime
#if defined(_WIN32) || defined(_WIN64)
// On Windows, gmtime_s is the thread-safe equivalent
inline struct tm* safe_gmtime(const time_t* timep, struct tm* result) {
    return gmtime_s(result, timep) == 0 ? result : nullptr;
}
#else
// On POSIX, gmtime_r is thread-safe
inline struct tm* safe_gmtime(const time_t* timep, struct tm* result) {
    return gmtime_r(timep, result);
}
#endif

namespace sola // 使用不同的命名空间
{

const int kMicroSecondsPerSecond = 1000 * 1000;

class Timestamp {
public:
    // 使用 std::chrono::microseconds 来存储从 epoch 开始的微秒数
    // 这样可以方便地与 std::chrono::system_clock::time_point 转换
    using underlying_type = std::chrono::microseconds;
    using clock           = std::chrono::system_clock; // Muduo Timestamp is based on UTC, system_clock is usually UTC

    // 默认构造: 无效时间戳 (epoch)
    Timestamp()
        : microSecondsSinceEpoch_(0) {}

    // 从自 epoch 以来的微秒数构造
    explicit Timestamp(int64_t microSecondsSinceEpochArg)
        : microSecondsSinceEpoch_(microSecondsSinceEpochArg) {}

    // 从 std::chrono::time_point 构造 (隐式转换，方便使用)
    Timestamp(clock::time_point tp)
        : microSecondsSinceEpoch_(
            std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch()).count()) {}

    void swap(Timestamp& that) { std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_); }

    std::string toString() const {
        std::ostringstream oss;
        int64_t            seconds      = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
        int64_t            microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;
        oss << seconds << "." << std::setw(6) << std::setfill('0') << microseconds;
        return oss.str();
    }

    std::string toFormattedString(bool showMicroseconds = true) const {
        time_t    seconds = static_cast<time_t>(secondsSinceEpoch());
        struct tm tm_time;

        // 使用线程安全的gmtime
        if (safe_gmtime(&seconds, &tm_time) == nullptr) {
            return "Invalid Time"; // Or throw an exception
        }

        std::ostringstream oss;
        oss << std::put_time(&tm_time, "%Y%m%d %H:%M:%S");
        if (showMicroseconds) {
            int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
            oss << "." << std::setw(6) << std::setfill('0') << microseconds;
        }
        return oss.str();
    }

    bool valid() const { return microSecondsSinceEpoch_ > 0; } // Muduo's definition of valid

    int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }

    time_t secondsSinceEpoch() const { return static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); }

    // 转换为 std::chrono::system_clock::time_point
    clock::time_point toTimePoint() const {
        return clock::time_point(std::chrono::microseconds(microSecondsSinceEpoch_));
    }

    static Timestamp now() { return Timestamp(clock::now()); }

    static Timestamp invalid() {
        return Timestamp(); // 0 microseconds since epoch
    }

    static Timestamp fromUnixTime(time_t t) { return fromUnixTime(t, 0); }

    static Timestamp fromUnixTime(time_t t, int microseconds) {
        return Timestamp(static_cast<int64_t>(t) * kMicroSecondsPerSecond + microseconds);
    }

private:
    int64_t microSecondsSinceEpoch_; // 存储自 epoch 以来的微秒数
};

// 比较操作符
inline bool operator<(Timestamp lhs, Timestamp rhs) {
    return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch();
}

inline bool operator==(Timestamp lhs, Timestamp rhs) {
    return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch();
}

inline bool operator!=(Timestamp lhs, Timestamp rhs) {
    return !(lhs == rhs);
}

inline bool operator<=(Timestamp lhs, Timestamp rhs) {
    return lhs < rhs || lhs == rhs;
}

inline bool operator>(Timestamp lhs, Timestamp rhs) {
    return rhs < lhs;
}

inline bool operator>=(Timestamp lhs, Timestamp rhs) {
    return rhs <= lhs;
}

inline double timeDifference(Timestamp high, Timestamp low) {
    int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
    return static_cast<double>(diff) / kMicroSecondsPerSecond;
}

inline Timestamp addTime(Timestamp timestamp, double seconds) {
    int64_t delta_us = static_cast<int64_t>(seconds * kMicroSecondsPerSecond);
    return Timestamp(timestamp.microSecondsSinceEpoch() + delta_us);
}

// 如果需要与 std::chrono::duration 直接进行算术运算
inline Timestamp operator+(Timestamp lhs, std::chrono::microseconds rhs_us) {
    return Timestamp(lhs.microSecondsSinceEpoch() + rhs_us.count());
}
inline Timestamp operator-(Timestamp lhs, std::chrono::microseconds rhs_us) {
    return Timestamp(lhs.microSecondsSinceEpoch() - rhs_us.count());
}
// 返回 duration
inline std::chrono::microseconds operator-(Timestamp lhs, Timestamp rhs) {
    return std::chrono::microseconds(lhs.microSecondsSinceEpoch() - rhs.microSecondsSinceEpoch());
}

} // namespace sola
